package org.minuframework.jdbc;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;
import org.minuframework.json.GsonUtils;
import com.google.common.collect.Lists;

public class JdbcConnection {

    public static final String DEFAULT_MYSQL_SQL = "SHOW TABLES";
    public static final String DEFAULT_ORACLE_SQL =
            "SELECT uo.object_name FROM user_objects uo WHERE uo.object_type = 'TABLE';";
    public static final String DEFAULT_SQL_SERVER_SQL = "SELECT name FROM sysobjects";
    public static final String DEFAULT_SYBASE_SQL = "SELECT name FROM sysobjects WHERE type = 'U';";
    public static final String DEFAULT_DB2_SQL =
            "SELECT tabname FROM syscat.tables WHERE tabschema = current SCHEMA;";
    public static final String DEFAULT_TABLE_NAME = "TABLE";
    public static final int DEFAULT_TABLE_NUM = 3;

    protected Properties properties;
    protected JdbcProperties jdbcProperties;
    /**
     * jdbc连接
     */
    protected Connection connection;

    public JdbcConnection() {}

    public JdbcConnection(Properties properties) {
        this.properties = properties;
    }

    public JdbcConnection(JdbcProperties jdbcProperties) {
        this.jdbcProperties = jdbcProperties;
    }

    public Connection getParamerRepository() {
        if (this.connection == null) {
            try {
                Class.forName(getJdbcProperties().getDriver());
                this.connection = DriverManager.getConnection(getJdbcProperties().getUrl(),
                        getJdbcProperties().getUsername(), getJdbcProperties().getPassword());
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
            }
        }
        return this.connection;
    }

    public Properties getProperties() {
        return this.properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public JdbcProperties getJdbcProperties() {
        if (this.jdbcProperties == null) {
            this.jdbcProperties = new JdbcProperties(this.properties);
        }
        return this.jdbcProperties;
    }

    public void setJdbcProperties(JdbcProperties jdbcProperties) {
        this.jdbcProperties = jdbcProperties;
    }

    public Connection getConnection() {
        return getParamerRepository();
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    public List<String> getTableNames() {
        List<String> result = Lists.newArrayList();
        try {
            DatabaseMetaData meta = getParamerRepository().getMetaData();
            String[] types = new String[] {DEFAULT_TABLE_NAME};
            ResultSet resultSet = meta.getTables(null, null, null, types);
            while (resultSet.next()) {
                result.add(resultSet.getString(DEFAULT_TABLE_NUM).trim());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static Connection openConnection() {
        return new JdbcConnection().getConnection();
    }

    public static Connection openConnection(Properties properties) {
        return new JdbcConnection(properties).getConnection();
    }

    public static Connection openConnection(JdbcProperties jdbcProperties) {
        return new JdbcConnection(jdbcProperties).getConnection();
    }

    public static void main(String[] args) {
        JdbcConnection connection = new JdbcConnection();
        System.out.println(GsonUtils.toGSONString(connection.getTableNames()));
    }

}
